package com.cdxy.service.impl;

import com.cdxy.dmr.dataObject.*;
import com.cdxy.dmr.repository.*;
import com.cdxy.enums.SaveTypeEnum;
import com.cdxy.model.dto.req.HomeIndexReq;
import com.cdxy.model.dto.req.HomeIndexSceneReq;
import com.cdxy.model.dto.req.SearchRecommendReq;
import com.cdxy.model.dto.req.UserWithLoginReq;
import com.cdxy.model.dto.req.app.AppMddReq;
import com.cdxy.model.dto.resp.BasicUserInfoResp;
import com.cdxy.model.dto.resp.HomeIndexResp;
import com.cdxy.model.dto.resp.HomeIndexSceneResp;
import com.cdxy.model.dto.resp.app.AppMddResp;
import com.cdxy.model.dto.resp.app.AppSearchRecommendResp;
import com.cdxy.model.info.HotelImgTopInfo;
import com.cdxy.model.info.IndexLoopInfo;
import com.cdxy.model.info.SaveInfo;
import com.cdxy.model.info.SceneImgTopInfo;
import com.cdxy.service.IIndexService;
import com.cdxy.service.IUserSaveService;
import com.cdxy.util.BeanUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: tangy
 * @Date: 2020/3/17 11:51
 */
@Service
public class IndexServiceImpl implements IIndexService {

    @Autowired
    private AxUserRepository axUserRepository;

    @Autowired
    private AxUserProfileRepository axUserProfileRepository;

    @Autowired
    private SceneRepository sceneRepository;

    @Autowired
    private HotelRepository hotelRepository;

    @Autowired
    private IndexLoopRepository indexLoopRepository;

    @Autowired
    private HotSearchRepository hotSearchRepository;

    @Autowired
    private AreaRepository areaRepository;

    @Autowired
    private IUserSaveService userSaveService;

    @Override
    public HomeIndexResp homeIndex(HomeIndexReq homeIndexReq) {
        HomeIndexResp homeIndexResp = new HomeIndexResp();
        Integer hotCityNum = homeIndexReq.getHotCity();

        List<IndexLoopDO> indexLoopDOList = indexLoopRepository.listOrderByCreateTime(homeIndexReq.getLoopIndex());
        List<IndexLoopInfo> loopInfoList = BeanUtil.copyPropertiesByFastJson(indexLoopDOList, IndexLoopInfo.class);

        List<SceneDO> sceneDOList = sceneRepository.listGroupByCityOrderBySearchNumAndReviewNum(hotCityNum);

        List<String> city = new ArrayList<>(hotCityNum);

        city.addAll(sceneDOList.stream().map(SceneDO::getCity).distinct().collect(Collectors.toList()));
        if (city.size() > hotCityNum) {
            for (int i = city.size(); i > hotCityNum; --i) {
                city.remove(i - 1);
            }
        } else if (city.size() < hotCityNum) {
            int lackNum = hotCityNum - city.size();
            List<AreaDO> areaDOList = areaRepository.listCityBySizeOrderByRand(lackNum, city);
            city.addAll(areaDOList.stream().map(AreaDO::getName).collect(Collectors.toList()));
        }

        homeIndexResp.setHotCityList(city);
        homeIndexResp.setIndexLoopInfoList(loopInfoList);

        return homeIndexResp;
    }

    @Override
    public HomeIndexSceneResp homeIndexScene(HomeIndexSceneReq homeIndexSceneReq) {
        Integer num = homeIndexSceneReq.getSceneNum();
        String city = homeIndexSceneReq.getCity();
        Integer axUid = homeIndexSceneReq.getAxUid();

        HomeIndexSceneResp homeIndexSceneResp = new HomeIndexSceneResp();

        List<SceneDO> sceneDOList;
        if (city.equals("全国")) {
            sceneDOList = sceneRepository.listOrderBySearchNumAndReviewNum(num);
        } else {
            sceneDOList = sceneRepository.listByCityOrderBySearchNu(city, num);
        }
        List<SceneImgTopInfo> sceneImgTopInfoList = BeanUtil.copyPropertiesByFastJson(sceneDOList, SceneImgTopInfo.class);

        homeIndexSceneResp.setMustPlaySceneList(sceneImgTopInfoList);

        if (axUid != null && sceneDOList.size() > 0) {
            List<Integer> ids = sceneDOList.stream().map(SceneDO::getSceneId).collect(Collectors.toList());
            List<SaveInfo> saveInfoList = userSaveService.saveStatusList(ids, axUid, SaveTypeEnum.SCENE);
            Map<Integer, SaveInfo> map = saveInfoList.stream().collect(Collectors.toMap(SaveInfo::getBusinessId, obj -> obj));
            sceneImgTopInfoList.forEach(sceneImgTopInfo -> {
                sceneImgTopInfo.setIsSave(map.get(sceneImgTopInfo.getSceneId()).getIsSave());
            });
        }
        return homeIndexSceneResp;
    }

    @Override
    public AppMddResp appMdd(AppMddReq appMddReq) {
        Integer hotelNum = appMddReq.getHotelNum();
        Integer sceneNum = appMddReq.getSceneNum();
        Integer axUid = appMddReq.getAxUid();
        String city = appMddReq.getCity();

        AppMddResp appMddResp = new AppMddResp();

        List<SceneDO> sceneDOList;
        if (StringUtils.isNotBlank(city) && !city.equals("全国")) {
            sceneDOList = sceneRepository.listByCityOrderBySearchNumAndReviewNum(city, sceneNum);
        } else {
            sceneDOList = sceneRepository.listOrderBySearchNumAndReviewNum(sceneNum);
        }
        List<SceneImgTopInfo> sceneImgTopInfoList = BeanUtil.copyPropertiesByFastJson(sceneDOList, SceneImgTopInfo.class);
        if (axUid != null && sceneDOList.size() > 0) {
            List<Integer> ids = sceneDOList.stream().map(SceneDO::getSceneId).collect(Collectors.toList());
            List<SaveInfo> saveInfoList = userSaveService.saveStatusList(ids, axUid, SaveTypeEnum.SCENE);
            Map<Integer, SaveInfo> map = saveInfoList.stream().collect(Collectors.toMap(SaveInfo::getBusinessId, obj -> obj));
            sceneImgTopInfoList.forEach(sceneImgTopInfo -> {
                sceneImgTopInfo.setIsSave(map.get(sceneImgTopInfo.getSceneId()).getIsSave());
            });
        }

        List<HotelDO> hotelDOList;
        if (StringUtils.isNotBlank(city) && !city.equals("全国")) {
            hotelDOList = hotelRepository.listByCityBySizeOrderBySearchNum(city, hotelNum);
        } else {
            hotelDOList = hotelRepository.listBySizeOrderBySearchNum(hotelNum);
        }
        List<HotelImgTopInfo> hotelImgTopInfoList = BeanUtil.copyPropertiesByFastJson(hotelDOList, HotelImgTopInfo.class);
        if (axUid != null && hotelDOList.size() > 0) {
            List<Integer> ids = hotelDOList.stream().map(HotelDO::getHotelId).collect(Collectors.toList());
            List<SaveInfo> saveInfoList = userSaveService.saveStatusList(ids, axUid, SaveTypeEnum.HOTEL);
            Map<Integer, SaveInfo> map = saveInfoList.stream().collect(Collectors.toMap(SaveInfo::getBusinessId, obj -> obj));
            hotelImgTopInfoList.forEach(hotelImgTopInfo -> {
                hotelImgTopInfo.setIsSave(map.get(hotelImgTopInfo.getHotelId()).getIsSave());
            });
        }

        appMddResp.setSceneImgTopInfoList(sceneImgTopInfoList);
        appMddResp.setHotelImgTopInfos(hotelImgTopInfoList);

        return appMddResp;
    }

    @Override
    public AppSearchRecommendResp appSearchRecommend(SearchRecommendReq searchRecommendReq) {
        Integer num = searchRecommendReq.getNum();

        List<HotSearchDO> hotSearchDOList;
        if (num == null || num < 1) {
            hotSearchDOList = hotSearchRepository.listOrderByCount(6);
        } else {
            hotSearchDOList = hotSearchRepository.listOrderByCount(num);
        }

        AppSearchRecommendResp appSearchRecommendResp = new AppSearchRecommendResp();
        appSearchRecommendResp.setRecommendTagList(hotSearchDOList.stream().map(HotSearchDO::getName).collect(Collectors.toList()));

        return appSearchRecommendResp;
    }

    @Override
    public BasicUserInfoResp basicUserInfo(UserWithLoginReq userWithLoginReq) {
        Integer axUid = userWithLoginReq.getAxUid();
        AxUserDO axUserDO = axUserRepository.getById(axUid);

        AxUserProfileDO axUserProfileDO = axUserProfileRepository.getById(axUid);

        BasicUserInfoResp basicUserInfoResp = BeanUtil.copyPropertiesByFastJson(axUserProfileDO, BasicUserInfoResp.class);
        basicUserInfoResp.setPhone(axUserDO.getMobile());

        return basicUserInfoResp;
    }
}
